package com.carey.blog.event.comment;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.json.JSONObject;

import com.carey.blog.event.EventTypes;
import com.carey.blog.framework.latke.Keys;
import com.carey.blog.framework.latke.event.AbstractEventListener;
import com.carey.blog.framework.latke.event.Event;
import com.carey.blog.framework.latke.event.EventException;
import com.carey.blog.framework.latke.event.EventManager;
import com.carey.blog.framework.latke.util.Strings;
import com.carey.blog.listener.CareyBlogServletListener;
import com.carey.blog.model.Comment;
import com.carey.blog.model.Page;
import com.carey.blog.model.Preference;
import com.carey.blog.repository.CommentRepository;
import com.carey.blog.repository.impl.CommentGAERepository;
import com.carey.blog.util.Preferences;
import com.google.appengine.api.mail.MailService;
import com.google.appengine.api.mail.MailService.Message;
import com.google.appengine.api.mail.MailServiceFactory;

/**
 * This listener is responsible for processing page comment reply.
 * 
 */
public final class PageCommentReplyNotifier extends
		AbstractEventListener<JSONObject> {

	/**
	 * Logger.
	 */
	private static final Logger LOGGER = Logger
			.getLogger(PageCommentReplyNotifier.class.getName());
	/**
	 * Comment repository.
	 */
	private CommentRepository commentRepository = CommentGAERepository
			.getInstance();
	/**
	 * Mail service.
	 */
	private MailService mailService = MailServiceFactory.getMailService();
	/**
	 * Preference utilities.
	 */
	private Preferences preferenceUtils = Preferences.getInstance();

	/**
	 * Constructs a {@link PageCommentReplyNotifier} object with the specified
	 * event manager.
	 * 
	 * @param eventManager
	 *            the specified event manager
	 */
	public PageCommentReplyNotifier(final EventManager eventManager) {
		super(eventManager);
	}

	@Override
	public void action(final Event<JSONObject> event) throws EventException {
		final JSONObject eventData = event.getData();
		final JSONObject comment = eventData.optJSONObject(Comment.COMMENT);
		final JSONObject page = eventData.optJSONObject(Page.PAGE);
		LOGGER.log(
				Level.FINER,
				"Processing an event[type={0}, data={1}] in listener[className={2}]",
				new Object[] { event.getType(), eventData,
						PageCommentReplyNotifier.class.getName() });
		final String originalCommentId = comment
				.optString(Comment.COMMENT_ORIGINAL_COMMENT_ID);
		if (Strings.isEmptyOrNull(originalCommentId)) {
			LOGGER.log(Level.FINER, "This comment[id={0}] is not a reply",
					comment.optString(Keys.OBJECT_ID));
			return;
		}

		try {
			final String commentEmail = comment
					.getString(Comment.COMMENT_EMAIL);
			final JSONObject originalComment = commentRepository
					.get(originalCommentId);
			final String originalCommentEmail = originalComment
					.getString(Comment.COMMENT_EMAIL);
			if (originalCommentEmail.equalsIgnoreCase(commentEmail)) {
				return;
			}

			final JSONObject preference = preferenceUtils.getPreference();
			if (null == preference) {
				throw new EventException("Not found preference");
			}

			final String blogTitle = preference
					.getString(Preference.BLOG_TITLE);
			final String adminEmail = preference
					.getString(Preference.ADMIN_EMAIL);

			final String commentContent = comment.getString(
					Comment.COMMENT_CONTENT).replaceAll(
					CareyBlogServletListener.ENTER_ESC, "<br/>");
			final String commentSharpURL = comment
					.getString(Comment.COMMENT_SHARP_URL);
			final Message message = new Message();
			message.setSender(adminEmail);
			message.setTo(originalCommentEmail);
			final String mailSubject = blogTitle
					+ ": New reply of your comment";
			message.setSubject(mailSubject);
			final String pageTitle = page.getString(Page.PAGE_TITLE);
			final String blogHost = preference.getString(Preference.BLOG_HOST);
			final String pageLink = "http://" + blogHost
					+ page.getString(Page.PAGE_PERMALINK);
			final String commentName = comment.getString(Comment.COMMENT_NAME);
			final String commentURL = comment.getString(Comment.COMMENT_URL);
			String commenter = null;
			if (!"http://".equals(commentURL)) {
				commenter = "<a target=\"_blank\" " + "href=\"" + commentURL
						+ "\">" + commentName + "</a>";
			} else {
				commenter = commentName;
			}

			final String mailBody = "Your comment on page[<a href='" + pageLink
					+ "'>" + pageTitle + "</a>] received an reply: <p>"
					+ commenter + ": <span><a href=\"http://" + blogHost
					+ commentSharpURL + "\">" + commentContent
					+ "</a></span></p>";
			message.setHtmlBody(mailBody);
			LOGGER.log(
					Level.FINER,
					"Sending a mail[mailSubject={0}, mailBody=[{1}] to [{2}]",
					new Object[] { mailSubject, mailBody, originalCommentEmail });
			mailService.send(message);
		} catch (final Exception e) {
			LOGGER.log(Level.SEVERE, e.getMessage(), e);
			throw new EventException("Reply notifier error!");
		}
	}

	/**
	 * Gets the event type {@linkplain EventTypes#ADD_COMMENT_TO_PAGE}.
	 * 
	 * @return event type
	 */
	@Override
	public String getEventType() {
		return EventTypes.ADD_COMMENT_TO_PAGE;
	}
}
